#include <iostream>
#include <fstream>
#include <string>
#include <iomanip> // for std::setprecision
#include <cstdlib> // for exit function

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h> // for close function

const int SIZE = 60;
using namespace std;

// int main(){
    // char automobile[50];
    // int year;
    // double aPrice;
    // double dPrice;

    // ofstream outfile;
    // outfile.open("cars.txt"); // Open the file for writing

    // cout << fixed;
    // cout.precision(2); // Set precision for floating-point output
    // cout.setf(ios::showpoint); // Show decimal point for floating-point numbers
    // cout << "Enter the make and model of the automobile: ";
    // cin.getline(automobile, 50); // Read the automobile make and model
    // cout << "Enter the model year: ";
    // cin >> year; // Read the model year
    // cout << "Enter the original asking price: ";
    // cin >> aPrice; // Read the original asking price
    // cout << "Enter the dealer's price: ";
    // cin >> dPrice; // Read the dealer's price


    // outfile << fixed;//定点表示 设定浮点数为定点表示法输出 以普通小数形式显示
    // outfile.precision(2); // 设置精度为2位小数
    // outfile.setf(ios::showpoint); // 强制显示小数点
    
    // outfile << "Enter the make and model of the automobile: " << automobile << endl;
    // outfile << "Enter the model year: " << year << endl;
    // outfile << "Enter the original asking price: " << aPrice << endl;
    // outfile << "Enter the dealer's price: " << dPrice << endl;

    
//==================================================file class==========================================================
//     char filename[SIZE];
//     ifstream infile;
//     cout  << "Enter the name of the file to open: ";
//     cin.getline(filename, SIZE);// Read the filename from user input
//     infile.open(filename); // Open the file
//     if(!infile.is_open()){
//         cout << "Error opening file: " << filename << endl;
//         cout << " program terminated." << endl;
//         exit(EXIT_FAILURE);//需要用到cstdlib头文件
        
//     }

//     double value;
//     double sum = 0.0;
//     int count = 0;

//     infile >> value;
//     while(infile.good()){
//         ++count;
//         sum += value;
//         infile >> value;
//     }
//     if(infile.eof()){//检查是否达到文件末尾
//         cout << "end of file reached.\n";
//     }
//     else if (infile.fail()){//没到末尾但是失败说明文件类型有问题
//         cout << " input terminated by data mismatch.\n";
//     }
//     else
//         cout << "input terminated by unknown reason.\n";

//     if(count == 0)
//         cout << "No data read from file.\n";
//     else{
//         cout << "The number of values read: " << count << endl;
//         cout << "The sum of the values is: " << sum << endl;
//         cout << "The average of the values is: " << (sum / count) << endl;
//     }
//     infile.close();

//     return 0;
// }

//=============================================================system file IO Open==================================================
// int main(int argc, char **argv){
//     int fd;
//     if(argc != 2){
//         printf("Usage: %s <filename>\n", argv[0]);
//         return 1;
//     }
//     fd = open(argv[1], O_RDWR); // Open the file for reading
//     if(fd < 0){
//         printf("can not open file %s\n",argv[1]);
//         printf("errno: %d\n", errno);
//         printf("err:%s\n",strerror(errno));// Get the error message
//         perror("open");// Print the error message

//     }
//     else{
//         printf("fd = %d\n", fd);
//     }
//     while(1){
//         sleep(10);
//     }
//     close(fd); // Close the file descriptor
//     return 0;
// }

//=============================================================system file IO Create==================================================
// int main(int argc, char **argv){
//     int fd;
//     if(argc != 2){
//         printf("Usage: %s <filename>\n", argv[0]);
//         return 1;
//     }
//     fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC,0644); // Open the file for reading
//     if(fd < 0){
//         printf("can not open file %s\n",argv[1]);
//         printf("errno: %d\n", errno);
//         printf("err:%s\n",strerror(errno));// Get the error message
//         perror("open");// Print the error message

//     }
//     else{
//         printf("fd = %d\n", fd);
//     }
//     while(1){
//         sleep(10);
//     }
//     close(fd); // Close the file descriptor
//     return 0;
// }

//==============================================================system file IO Write==================================================
/*
 * ./main 1.txt  str1  str2
 */

// int main(int argc, char **argv){
//     int fd;
//     int i;
//     int len;
//     if(argc < 3){
//         printf("Usage: %s <filename> <string1> <string2> ... \n", argv[0]);
//         return 1;
//     }
//     fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC,0644); // Open the file for reading
//     if(fd < 0){
//         printf("can not open file %s\n",argv[1]);
//         printf("errno: %d\n", errno);
//         printf("err:%s\n",strerror(errno));// Get the error message
//         perror("open");// Print the error message

//     }
//     else{
//         printf("fd = %d\n", fd);
//     }
//     for(i = 2; i < argc; i++){
//         len = write(fd, argv[i], strlen(argv[i])); // Write each string to the file
//         if(len != strlen(argv[i])){
//             perror("write");
//             break;
//         }
//         write(fd,"\n\r",2);
//     }
//     close(fd); // Close the file descriptor
//     return 0;
// }

//==============================================================system file IO Write(2)==================================================
/*
 * lseek函数用于在文件中移动读写位置。
 * 
 * */
// int main(int argc, char **argv){
//     int fd;
//     int i;
//     int len;
//     if(argc != 2){
//         printf("Usage: %s <filename> \n", argv[0]);
//         return 1;
//     }
//     fd = open(argv[1], O_RDWR|O_CREAT, 0644); // Open the file for reading
//     if(fd < 0){
//         printf("can not open file %s\n",argv[1]);
//         printf("errno: %d\n", errno);
//         printf("err:%s\n",strerror(errno));// Get the error message
//         perror("open");// Print the error message

//     }
//     else{
//         printf("fd = %d\n", fd);
//     }

//     printf("lseek to offset 3 from file head"); 
//     lseek(fd, 3, SEEK_SET);//会导致文件指针移动到文件开头的3个字节处，在这之后写入比如“123”3个字符，会导致原本的这里的三个字符被覆盖

//     write(fd, "123",3);

//     close(fd); // Close the file descriptor
//     return 0;
// }

//===============================================================system file IO Read==================================================
/* ./read 2.txt
 * argc = 2
 * argv[0] = "./read"
 * argv[1] = "2.txt"
 */
// int main(int argc, char **argv){
//     int fd;
//     int i;
//     int len;
//     unsigned char buf[100];//bufferto hold read data
//     if(argc != 2){
//         printf("Usage: %s <filename> \n", argv[0]);
//         return 1;
//     }
//     fd = open(argv[1], O_RDONLY, 0644); // Open the file for reading
//     if(fd < 0){
//         printf("can not open file %s\n",argv[1]);
//         printf("errno: %d\n", errno);
//         printf("err:%s\n",strerror(errno));// Get the error message
//         perror("open");// Print the error message

//     }
//     else{
//         printf("fd = %d\n", fd);
//     }

//     /*read and printf*/
//     while (1)
//     {
//         len = read(fd, buf, sizeof(buf)-1);// Read up to 10 bytes from the file
//         if(len < 0){
//             perror("read");
//             return -1;
//         }
//         else if(len == 0){
//             break;
//         }
//         else{
//             buf[len-1] = '\0'; // Null-terminate the string
//             printf("%s", buf); // Print the read data
//         }
//     }
//     //当调用read函数时会有一个指针，指向当前读取位置，每次读取后这个指针会自动向后移动相应的字节数
//     //当文件读到末尾时，read函数会返回0，表示没有更多的数据可读
//     //如果在读取过程中发生错误，read函数会返回-1，并设置errno以指示错误类型

//     close(fd); // Close the file descriptor
//     return 0;
// }

//==================================================================read file & compile execel====================================================================
/* ./process_excel data.csv result.csv
 * argc = 3
 * argv[0] = "./process_execel"
 * argv[1] = "data.csv"
 * argv[2] = "result.csv"
 */

 /* 返回值：
  * n表示读到一行数据的数据个数 n>=0
  * -1表示读取到文件尾部或者出错
  */
static int read_line(int fd, unsigned char *buf){
    /*循环读入一个字符*/

    /*如何判断已经读完一行？读到0x0d  0x0a（回车换行十六进制）*/
    unsigned char c;
    int len;
    int i = 0;
    int err = 0;

    while(1){
        len = read(fd, &c, 1);
        if(len <= 0){
            err = -1;
            break;
        }//len <= 0表示读到了文件尾部
        else{
            if(c != '\r' && c != '\n'){
                buf[i] = c;
                i++;
            }
            else{
                /*碰到回车换行*/
                err = 0;
                break;
            }
        }
    }
    buf[i] = '\0'; // Null-terminate the string
    if(err && (i == 0)){
        return -1;//读到数据尾部 并且一个数据都没有进来
    }
    else{
        return i; // Return the number of characters read
    }
}

void process_data( unsigned char *data_buf,  unsigned char *result_buf){
    /*示例1 data_buf = " , 语文， 数学， 英语， 总分， 评价"
     *      result_buf = "语文, 数学, 英语, 总分, 评价"
     *示例2 data_buf = " 张三， 90， 91， 92，, "
     *     result_buf = "张三, 90, 91, 92，273，A+" 
     * */
    char name[100];
    int score[3];
    int sum;
    const char *levels[] = {"A+", "A", "B"};
    int level;

    if(data_buf[0] == 0xef){//对于utf-8编码的文件，前三个字符是0xef，0xbb，0xbf
        strcpy((char*)result_buf, (char *)data_buf);
    }
    else{
        sscanf((char*)data_buf, "%[^,],%d,%d,%d,",name, &score[0], &score[1], &score[2]);
        //printf("result: %s, %d, %d, %d\n\r",name, score[0], score[1], score[2]);
        //printf("result: %s -----> get name------> %s\n\r",data_buf, name);
        sum = score[0] + score[1] + score[2];
        if(sum >= 270){
            level = 0;
        }
        else if(sum >= 240){
            level = 1;
        }
        else{
            level = 2;
        }
        sprintf((char*)result_buf, "%s, %d, %d, %d, %d, %s", name, score[0], score[1], score[2], sum, levels[level]);
        //printf("result:%s", result_buf);
    
    }//%[^,]表示读取直到遇到逗号为止的所有字符，存储在name中
}

int main(int argc, char **argv){
    int fd_data, fd_result;
    int i;
    int len;
    unsigned char data_buf[1000];
    unsigned char result_buf[1000];
    
    if(argc != 3){
        printf("Usage: %s <data csv file> <result csv file>\n", argv[0]);
        return 1;
    }
    fd_data = open(argv[1], O_RDONLY); // Open the file for reading

    if(fd_data < 0){
        printf("can not open file %s\n",argv[1]);
        perror("open");// Print the error message
        return -1;

    }
    else{
        printf("data file fd = %d\n", fd_data);
    }

    fd_result = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644); // Open the result file for writing
    if (fd_result < 0) {
        printf("can not open file %s\n", argv[2]);
        perror("open"); // Print the error message
        
        return -1;
    } else {
        printf("result file fd = %d\n", fd_result);
    }
    
    /*read and printf*/
    while (1)
    {
        /*从数据文件里读取一行*/
        len = read_line(fd_data,data_buf); // Read a line from the data file
        if(len == -1){
            break;
        }
        // if(len!=0)
        //     printf("line: %s\n\r",data_buf);调试信息 测试read_line是否成功 √
        /*处理数据*/
        if(len != 0)
        {
            process_data(data_buf, result_buf);
            /*写入结果文件*/
            //write_data(result_buf,fd_result);
            write(fd_result, result_buf, strlen((char*)result_buf)); // Write the processed data to the result file
            write(fd_result, "\r\n", 2); // Write a newline character to the result file
 
        }
        
    }
    
    close(fd_data); // Close the file descriptor
    close(fd_result); // Close the result file descriptor
    return 0;
}
